package com.oocl.chatroom.server.infohandle;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;

import org.json.JSONException;
import org.json.JSONObject;

import com.oocl.chatroom.network.protocol.Message;
import com.oocl.chatroom.server.ChatServer;
import com.oocl.chatroom.server.OnlineSocket;
import com.oocl.chatroom.server.sender.Sender;

public class MsgParseImpl implements MsgParse{
     private OnlineSocket onlineSocket;
     private Map<String,OnlineSocket> users;
     private ChatServer server;
     
     public void setServer(ChatServer server) {
    	 this.server = server;
     }
     
     public MsgParseImpl(OnlineSocket onlineSocket,
    		 Map<String,OnlineSocket> users){
    	 this.onlineSocket = onlineSocket;
    	 this.users = users;
     }
     
     
    public OnlineSocket getOnlineSocket() {
		return onlineSocket;
	}
	public void setOnlineSocket(OnlineSocket onlineSocket) {
		this.onlineSocket = onlineSocket;
	}
	public Map<String, OnlineSocket> getUsers() {
    	 return users;
     }
     
     public void setUsers(Map<String, OnlineSocket> users) {
    	 this.users = users;
     }
     
     public boolean solveMessage() {
    	 boolean result = true;
       try {
    	   BufferedReader in = onlineSocket.getIn();
		   String json =  in.readLine();
		   Message msg =  changeToMessage(json);
    	   int type = msg.getType();
    	  if(type==0||type==1){
    		  System.out.println(msg.getSender()+"  "+msg.getContent());
    		 String receiver = msg.getReceiver();
    		 if("*".equals(receiver)){
    			 sendMsgToAll(msg);
    		 }else{
    			 sendMsgToOne(msg,receiver);
    		 }
    	   }else if(type==2){
    		   nodifyLoginMsg(msg);
    	   }else if(type==3){
    		   nodifyDownlineMsg(msg);
    	   }else if(type==9){
    		   closeServer();
    	   }else if(type==10){
    		   getList();
    	   }
         } catch (IOException e) {
        	result = false;
        	String downLiner = onlineSocket.getName();
            users.remove(downLiner);
            users.put(downLiner, null);
			Message downlineMsg = new Message(downLiner,3,"server","*",System.currentTimeMillis());
			Set<String> names = users.keySet();
			for(String name:names){
				if(!name.equals(downLiner)&&users.get(name)!=null){
					OnlineSocket onlineSocket = users.get(name);
					PrintWriter o = onlineSocket.getOut();
					new Thread(new Sender(downlineMsg,o)).start();				
				}
			}
        }
    	 return result;
     }
     
	private void getList() {
		
	}

	private void closeServer() {
		PrintWriter out = onlineSocket.getOut(); 
		Set<String> names = users.keySet();
		Message shutdownMsg = new Message("server has closed!",9,"","",new Date().getTime());
		for(String name:names){
			PrintWriter o =users.get(name).getOut();
			JSONObject jOb = new JSONObject(shutdownMsg);
			String json = jOb.toString();
					o.println(json);
					o.flush();
		}
		try {
		for(String name:names){
				users.get(name).getIn().close();
				users.get(name).getOut().close();
				users.get(name).getSocket().close();
		}
			server.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	private Message changeToMessage(String json) {
		Message msg = new Message();
		try {
			JSONObject jOb = new JSONObject(json);
			System.out.println(jOb.getInt("type"));
			msg.setContent( jOb.getString("content"));
			msg.setDate(jOb.getLong("date"));
			msg.setSender( jOb.getString("sender"));
			msg.setReceiver(jOb.getString("receiver"));
			msg.setType(Integer.parseInt(jOb.getString("type")));
		}catch (JSONException e) {
			e.printStackTrace();
		}

		return msg;
	}


	public void nodifyDownlineMsg(Message msg) throws IOException {
		// TODO Auto-generated method stub
		String sender = msg.getSender();
		Set<String> names = users.keySet();
		OnlineSocket downlineSocket = users.get(sender);
		downlineSocket.getSocket().close();
		users.remove(sender);
		Message onlineMsg = new Message(sender,3,"server","*",System.currentTimeMillis());
		for(String name:names){
			if(!name.equals(sender)&&users.get(name)!=null){
				OnlineSocket onlineSocket = users.get(name);
				PrintWriter o = onlineSocket.getOut();
				new Thread(new Sender(onlineMsg,o)).start();				
			}
		}
	}
	
	private void nodifyLoginMsg(Message msg) throws IOException {
		String sender = msg.getSender();
		System.out.println(sender+"  is on line ...");
		onlineSocket.setName(sender);
		users.put(sender, onlineSocket);
		Set<String> names = users.keySet();
		String namesStr = "";
		Message onlineMsg = new Message(sender,2,"server","*",System.currentTimeMillis());
		for(String name:names){
			if(!name.equals(sender)&&users.get(name)!=null){
				namesStr += name+";";
				OnlineSocket onlineSocket = users.get(name);
				PrintWriter o = onlineSocket.getOut();
				new Thread(new Sender(onlineMsg,o)).start();				
			}
		}
		Message notifyListMsg = new Message(namesStr,4,"server",sender,System.currentTimeMillis()); 
		OnlineSocket onlineSocket = users.get(sender);
		PrintWriter o = onlineSocket.getOut();
		new Thread(new Sender(notifyListMsg,o)).start();
	}
	
	
	
	private void sendMsgToOne(Message msg, String receiver) throws IOException {
		// TODO Auto-generated method stub
		OnlineSocket onlineSocket = users.get(receiver);
		PrintWriter o = onlineSocket.getOut();
		new Thread(new Sender(msg,o)).start();
	}
	
	
	
	private void sendMsgToAll(Message msg) throws IOException {
		// TODO Auto-generated method stub
		Set<String> names = users.keySet();
		for(String name:names){
			if(!name.equals(msg.getSender())&&users.get(name)!=null){
				OnlineSocket onlineSocket = users.get(name);
				PrintWriter o = onlineSocket.getOut();
				new Thread(new Sender(msg,o)).start();				
			}
		}
	}

         
}
